#include "attr.h"

#define BIT_TO_BYTE_LEN(x) (x / 8)
static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
static const uint16_t character_client_config_uuid =
	ESP_GATT_UUID_CHAR_CLIENT_CONFIG;

void set_service_declaration(esp_gatts_attr_db_t *attr, struct gatts_service *s)
{
	attr->attr_control.auto_rsp = ESP_GATT_RSP_BY_APP;
	attr->att_desc.uuid_length = ESP_UUID_LEN_16;
	attr->att_desc.uuid_p = (uint8_t *)&primary_service_uuid;
	attr->att_desc.perm = ESP_GATT_PERM_READ;
	attr->att_desc.max_length = BIT_TO_BYTE_LEN(s->uuid.bit_len);
	attr->att_desc.length = BIT_TO_BYTE_LEN(s->uuid.bit_len);
	attr->att_desc.value = get_uuid_u8_pointer(&s->uuid);
}

void set_char_declaration(esp_gatts_attr_db_t *attr, struct gatts_char *c)
{
	attr->attr_control.auto_rsp = ESP_GATT_RSP_BY_APP;
	attr->att_desc.uuid_length = ESP_UUID_LEN_16;
	attr->att_desc.uuid_p = (uint8_t *)&character_declaration_uuid;
	attr->att_desc.perm = ESP_GATT_PERM_READ;
	attr->att_desc.max_length = sizeof(uint8_t);
	attr->att_desc.length = sizeof(uint8_t);
	attr->att_desc.value = &c->perm;
}

void set_char_value(esp_gatts_attr_db_t *attr, struct gatts_char *c)
{
	attr->attr_control.auto_rsp = ESP_GATT_RSP_BY_APP;
	attr->att_desc.uuid_length = ESP_UUID_LEN_16;
	attr->att_desc.uuid_p = (uint8_t *)&c->uuid.uuid.uuid16;
	// (uint8_t *)&((uint16_t[]){ ESP_GATT_UUID_PRI_SERVICE });
	attr->att_desc.perm = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;
	attr->att_desc.max_length = c->max_length;
	attr->att_desc.length = c->length;
	attr->att_desc.value = c->value;
}

void set_cccd(esp_gatts_attr_db_t *attr, struct gatts_char *c)
{
	attr->attr_control.auto_rsp = ESP_GATT_RSP_BY_APP;
	attr->att_desc.uuid_length = ESP_UUID_LEN_16;
	attr->att_desc.uuid_p = (uint8_t *)&character_client_config_uuid;
	attr->att_desc.perm = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;
	attr->att_desc.max_length = sizeof(uint16_t);
	attr->att_desc.length = sizeof(uint16_t);
	attr->att_desc.value = (uint8_t *)&c->cccd;
}

// XXX
void print_attr(const esp_gatts_attr_db_t *attr)
{
	printf("auto_rsp: %u\n", attr->attr_control.auto_rsp);
	printf("uuid_length: %u\n", attr->att_desc.uuid_length);
	printf("uuid_p: %p -> 0x%04X\n", attr->att_desc.uuid_p,
	       *(uint16_t *)attr->att_desc.uuid_p);
	printf("perm: 0x%04X\n", attr->att_desc.perm);
	printf("max_length: %u\n", attr->att_desc.max_length);
	printf("length: %u\n", attr->att_desc.length);
	printf("value: %p", attr->att_desc.value);
	for (int i = 0; i < attr->att_desc.length; i++) {
		if (i % 8 == 0) {
			printf("\n");
		}
		printf("%02X ", attr->att_desc.value[i]);
	}
	printf("\n\n");
}
